#include <memory>
#include "Common.hpp"
#include "Http.hpp"
#include "Util.hpp"
#include "Sesssion.hpp"


std::unordered_map<int, char*> Weeks = {
    {0, (char*)"Sun"}, {1, (char*)"Mon"}, {2, (char*)"Tues"}, {3, (char*)"Wed"}, {4, (char*)"Thu"}, {5, (char*)"Fri"}, {6, (char*)"Sat"}
};

std::unordered_map<int, std::string> Months = {
    {0, "Jan"},  // 0 对应 Jan（1月）
    {1, "Feb"},  // 1 对应 Feb（2月）
    {2, "Mar"},  // 2 对应 Mar（3月）
    {3, "Apr"},  // 3 对应 Apr（4月）
    {4, "May"},  // 4 对应 May（5月）
    {5, "Jun"},  // 5 对应 Jun（6月）
    {6, "Jul"},  // 6 对应 Jul（7月）
    {7, "Aug"},  // 7 对应 Aug（8月）
    {8, "Sep"},  // 8 对应 Sep（9月）
    {9, "Oct"},  // 9 对应 Oct（10月）
    {10, "Nov"}, // 10 对应 Nov（11月）
    {11, "Dec"}, // 11 对应 Dec（12月）
    {12, "Invalid"} // 12 作为无效月份处理
};



//这里就简单模拟一下就好了，直接以txt文本返回
//今天就直接拿登录来做模拟测试
void Login(HttpRequest& req, HttpResponse& resp, SessionManager& manager){
    //此时，不知道参数在正文还是在uri上
    //但是，在HttpRequest类内，用参数_args保存了！
    std::string args = req.GetArgs() == "" ? req.GetText() : req.GetArgs();
    resp.SetCodeAndDesc(200);
    //上面是获取参数，就是账户和密码
    //需要手动的把账户密码什么给提取出来
    //username=xxx&password=xxx 
    size_t pos1 = args.find("username");
    size_t pos2 = args.find('&', pos1);
    std::string username = args.substr(pos1, pos2 - pos1);

    //后序可能会有别的参数，所以，我们需要判断后面还有没有...
    size_t pos3 = args.find("password");
    size_t pos4 = args.find('&', pos3);
    std::string password = args.substr(pos3, pos4 - pos3);

    session_ptr ps = std::make_shared<Session>(username, password);
    std::string sessionid = manager.AddSession(ps);

    std::cout << sessionid << std::endl;

    //还可以设置一下cookie的过期时间(这个过期时间可以放在session类内)
    //expires=Thu, 18 Dec 2024 12:00:00 UTC;
    /* char timebuffer[128] = {0};
    struct tm* t = gmtime(ps->GetOutTimeAddr());
    snprintf(timebuffer, sizeof(timebuffer) - 1, "%s, %02d, %s %d %02d:%02d:%02d %s", 
        Weeks[t->tm_wday], t->tm_mday, Months[t->tm_mon].c_str(), t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec, "UTC"
    );
    resp.SetHeaders("Set-Cookie", "expires=" + std::string(timebuffer)); */


    //我们要把对应的参数写到cookie
    //这里改动了，应该是把sessionid写到cookie
    resp.SetHeaders("Set-Cookie", "sessionid=" + sessionid); //今天这里使用的是unordered_map会导致第二次插入其它的Set-cookie出问题！(没办法再插入了)
    //但是这里我不敢改成unordered_multimap，因为没有实现[]重载！  -》 改了就会导致代码逻辑全部出问腿！
    //这里再HttpResponse那里写了对应的修改方式了！这里我们就不写了，其实一开始使用unordered_multimap或者vector<string>是更方便的！

    //要不然就得设置到对应的cookie中，使用;进行分割，这样子就需要从应答中把对应的报头提取出来，这样也是可以的，这里也先不写了！！！！！！！！！


    //这里就不做验证账户密码了，直接登录成功就好！
    

    //正文就是登陆成功的页面
    std::string text;//正文
    std::string path = webroot + "/" + "success_login.html";
    Util::ReadFileContent(path, &text);
    resp.SetText(text);


    resp.SetHeaders("Content-Length", std::to_string(text.size()));
    resp.SetHeaders("Content-Type", MimeTypes().getMimeType(".html"));
}



//用来启动服务器的
// ./myhttp.exe server_port
int main(int argc, char* argv[]){
    if(argc != 2){
        std::cout << "please usage : ./myhttp.exe server_port" << std::endl;
        exit(USAGE_ERROR);
    }

    uint16_t server_port = std::stoi(argv[1]);
    std::unique_ptr<Http> http_server = std::make_unique<Http>(server_port);

    http_server->HttpServerInit();
    http_server->RegisterRoute("/login", Login);
    //http_server->RegisterRoute("/register", Register);
    http_server->HttpServerStart();
    return 0;
}